package cn.ad.service;

import cn.ad.exception.StrategyGroupValidateException;
import cn.ad.exception.StrategyValidateException;
import cn.ad.handler.SqlSessionHandler;
import cn.ad.interceptor.PageParameter;
import cn.ad.model.BaseMenuModel;
import cn.ad.model.ResultSetList;
import cn.ad.model.StrategyGroupModel;
import cn.ad.entity.Platform;
import cn.ad.entity.StrategyGroup;
import cn.ad.entity.StrategyGroupPlatformMap;
import com.alibaba.druid.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * User: shirongkang
 * Date: 2016/8/29
 * Time: 17:54
 * Desc:策略分组业务实现类
 */
@Service
public class StrategyGroupService {

    private static Logger logger = LoggerFactory.getLogger(StrategyGroupService.class);

    @Autowired
    private SqlSessionHandler sqlSessionHandler;

    @Autowired
    private CampaignService campaignService;

    @Autowired
    private PlatformService platformService;


    @Transactional
    public ResultSetList<StrategyGroupModel> findStrategyGroups(Map<String, Object> searchMap, PageParameter pageInfo) {
        //获取到策略列表
        List<StrategyGroupModel> strategyGroupList = sqlSessionHandler.selectList("strategyGroupMapper.strategyGroup:list:page", searchMap, pageInfo);
        //组成BO对象
        ResultSetList<StrategyGroupModel> list = new ResultSetList<>(pageInfo.getTotalCount(), strategyGroupList);
        return list;
    }

    @Transactional(readOnly = true)
    public boolean checkStrategrGroup(Integer campaignId) {
        return null != campaignService.getCampaignById(campaignId) ? true :false;
    }

    @Transactional
    public boolean checkPlatfrom(Integer[] platformIds, String resType) {
        for(int id : platformIds) {
            Platform platform = platformService.getPlatformById(id);
            if(null == platform) {
                return false;
            }else if(!resType.equals(platform.getResType())){
                return false;
            }
        }
        return true;
    }

    @Transactional()
    public void saveOrUpdateStrategrGroup(StrategyGroup strategyGroup,Integer[] platformIds) {
        if(null != strategyGroup) {
            //订单是否有效
            this.checkStrategrGroupCampaign(strategyGroup.getCampaignId());
            //验证策略分组是否存在状态临界值
            this.checkStrategrGroupStatus(strategyGroup);
            //平台数据是否有效
            if(!this.checkPlatfrom(platformIds,strategyGroup.getResourceType())) {
                throw new StrategyGroupValidateException(StrategyGroupValidateException.ErrorCode.STRATEGYGROUP_NOTFOUND_PLATFORM);
            }
            //创建
            if(strategyGroup.getId() == 0) {
                //该订单下是否存在相同名称的策略分组记录
                if(!this.checkStrategyGroup(strategyGroup.getName(),strategyGroup.getCampaignId())) {
                    throw new StrategyGroupValidateException(StrategyGroupValidateException.ErrorCode.STRATEGYGROUP_EXIST);
                }
                sqlSessionHandler.insert("strategyGroupMapper.insert",strategyGroup);
                this.saveStrategyGroupPlatform(strategyGroup.getId(),platformIds);
            }else {//更新
                //策略分组是否存在
                this.checkStrategyGroup(strategyGroup.getId(),strategyGroup.getCampaignId());
                sqlSessionHandler.update("strategyGroupMapper.update",strategyGroup);
                //清除策略分组与平台之间的关系数据
                sqlSessionHandler.update("strategyGroupPlatformMapper.deleteByStrategyGroupId:physics",strategyGroup.getId());
                this.saveStrategyGroupPlatform(strategyGroup.getId(),platformIds);
            }
        }
    }

    /**
     * 储存策略分组与平台关系
     */
    private int saveStrategyGroupPlatform(int strategyGroupId,Integer[] platformIds) {
        List<StrategyGroupPlatformMap> strategyGroupPlatformMaps = new ArrayList<>();
        StrategyGroupPlatformMap strategyGroupPlatformMap = null;
        for(int platformId : platformIds){
            strategyGroupPlatformMap = new StrategyGroupPlatformMap();
            strategyGroupPlatformMap.setPlatformId(platformId);
            strategyGroupPlatformMap.setStrategyGroupId(strategyGroupId);
            strategyGroupPlatformMaps.add(strategyGroupPlatformMap);
        }
        return sqlSessionHandler.insert("strategyGroupPlatformMapper.insert:list",strategyGroupPlatformMaps);
    }

    @Transactional
    public void updateStatusStrategyGroup(StrategyGroup strategyGroup) throws StrategyGroupValidateException{
        //订单是否有效
        this.checkStrategrGroupCampaign(strategyGroup.getCampaignId());
        //策略分组是否存在
        this.checkStrategyGroup(strategyGroup.getId(),strategyGroup.getCampaignId());
        //验证策略分组是否存在状态临界值
        this.checkStrategrGroupStatus(strategyGroup);
        sqlSessionHandler.update("strategyGroupMapper.updateStatus",strategyGroup);
    }

    @Transactional
    public void updateStrategyGroup(StrategyGroup strategyGroup) throws StrategyGroupValidateException{
        //订单是否有效
        this.checkStrategrGroupCampaign(strategyGroup.getCampaignId());
        //策略分组是否存在
        this.checkStrategyGroup(strategyGroup.getId(),strategyGroup.getCampaignId());
        StrategyGroup strategyGroupObj = new StrategyGroup();
        strategyGroupObj.setId(strategyGroup.getId());
        strategyGroupObj.setDayBudget(strategyGroup.getDayBudget());
        sqlSessionHandler.update("strategyGroupMapper.update",strategyGroupObj);
    }

    /**
     * 验证订单是否有效
     * @param id
     */
    private void checkStrategrGroupCampaign(int id){
        //订单是否有效
        if(!this.checkStrategrGroup(id)) {
            throw new StrategyGroupValidateException(StrategyGroupValidateException.ErrorCode.STRATEGYGROUP_NOTFOUND_COMPAGIN);
        }
    }
    /**
     * 验证策略分组是否存在
     * @param id
     */
    private void checkStrategyGroup(int id,int campaignId){
        //策略分组是否存在
        StrategyGroup strategyGroupObj = this.findStrategyGroupById(id,campaignId);
        if(null == strategyGroupObj) {
            throw new StrategyGroupValidateException(StrategyValidateException.ErrorCode.STRATEGY_STRATEGYGROUP_NOTFOUND);
        }
    }
    /**
     * 验证策略分组是否存在状态临界值
     * @param strategyGroup
     */
    private void checkStrategrGroupStatus(StrategyGroup strategyGroup){
        if(strategyGroup.getStatus() > 2) {
            throw new StrategyGroupValidateException(StrategyGroupValidateException.ErrorCode.STRATEGYGROUP_STATUS);
        }
    }

    @Transactional
    public void deleteStrategyGroup(int id,int campaignId) throws StrategyGroupValidateException{
        //订单是否有效
        this.checkStrategrGroupCampaign(campaignId);
        //策略分组是否存在
        this.checkStrategyGroup(id,campaignId);
        sqlSessionHandler.update("strategyGroupMapper.delete",id);
    }

    @Transactional
    public StrategyGroup findStrategyGroupById(int id,int campaignId) {
        if(id == 0 || campaignId == 0) {
            return null;
        }
        Map<String,Object> params = new HashMap<>();
        params.put("id",id);
        params.put("campaignId",campaignId);
        return sqlSessionHandler.selectOne("strategyGroupMapper.selectById",params);
    }

    @Transactional
    public boolean checkStrategyGroup(String name, int campaignId) {
        if(StringUtils.isEmpty(name) || campaignId == 0) {
            return false;
        }
        Map<String,Object> params = new HashMap<>();
        params.put("name",name);
        params.put("campaignId",campaignId);
        return  (Integer)sqlSessionHandler.selectOne("strategyGroupMapper.strategyGroup:checkname",params) == 0 ? true : false;
    }


    @Transactional
    public List<BaseMenuModel> findStrategyGroupList(int campaignId) {
        return sqlSessionHandler.selectList("strategyGroupMapper.select:base:strategyGroup:list", campaignId);
    }
}
